import React, { PureComponent, Fragment } from 'react';
import { Card, Form, Row, Col, DatePicker, Spin, Button, Table, Icon, Tooltip as AntdTooltip, Badge, Select } from 'antd';
import { Chart, Axis, Tooltip, Geom, Label } from 'bizcharts';
import { connect } from 'dva';
import { Link } from 'dva/router';
import moment from 'moment';
import lodash from 'lodash';
import Debounce from 'lodash-decorators/debounce';
import Bind from 'lodash-decorators/bind';
import { fmtThousands, fmtBytes, fmtDateTime, fmtTime } from '../../utils/fmt'
import { SummaryHistogramArray } from '../../utils/enum'
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
// import classNames from 'classnames';
import styles from './Summary.less'

@connect(({ GlobalEnumModel, SummaryModel, loading }) => ({
  GlobalEnumModel,
  SummaryModel,
  pageLoading: loading.effects['SummaryModel/query'],
  queryHistogramLoading: loading.effects['SummaryModel/queryHistogram'],
}))
@Form.create()
export default class Summary extends PureComponent {

  state = {
    screenHeight: document.documentElement.clientHeight,
  };

  // 数据初始化
  componentDidMount() {
    window.addEventListener('resize', this.handleHeight);
    const { dispatch } = this.props;
    dispatch({ type: 'GlobalEnumModel/allSysName' });
    dispatch({ type: 'SummaryModel/query' });
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleHeight);
  }

  // 动态设置高度
  @Bind()
  @Debounce(400)
  handleHeight = () => {
    const screenHeight = document.documentElement.clientHeight;
    this.setState({ screenHeight });
  };

  // 查询页面所有数据
  queryPageData = (e) => {
    if (e) e.preventDefault();
    const { dispatch, form: { getFieldValue } } = this.props;
    // const histogramPrefix = getFieldValue('histogramPrefix');
    const index = getFieldValue('index');
    const timeRange = getFieldValue('timeRange');
    dispatch({ type: 'SummaryModel/query', payload: { min: fmtDateTime(timeRange[0]), max: fmtDateTime(timeRange[1]), index } });
  }

  // 查询参数发生变化 -> 刷新页面数据
  sysNameChange = (index) => {
    const { dispatch } = this.props;
    lodash.delay(() => dispatch({ type: 'SummaryModel/query', payload: { index } }), 100);
  }

  // 查询参数发生变化 -> 刷新页面数据
  timeRangeChange = () => {
    const { dispatch, form: { getFieldValue } } = this.props;
    const timeRange = getFieldValue('timeRange');
    lodash.delay(() => dispatch({ type: 'SummaryModel/query', payload: { min: fmtDateTime(timeRange[0]), max: fmtDateTime(timeRange[1]) } }), 500);
  }

  // 直方图类型发生变化 -> 刷新直方图数据
  histogramPrefixChange = (histogramPrefix) => {
    const { dispatch } = this.props;
    dispatch({ type: 'SummaryModel/queryHistogram', payload: { histogramPrefix } });
  }

  // 查询表单
  queryForm() {
    const { form: { getFieldDecorator }, GlobalEnumModel: { sysNameList, currentSysName }, SummaryModel: { queryParam }, pageLoading, queryHistogramLoading } = this.props;
    const timeRangeInitialValue = [
      queryParam.min ? moment(queryParam.min) : moment().startOf('day').subtract(1, 'day'),
      queryParam.max ? moment(queryParam.max) : moment().endOf('day'),
    ];
    return (
      <Form onSubmit={this.queryPageData} layout="inline">
        <Row gutter={{ md: 0, lg: 0, xl: 0 }}>
          <Form.Item label="选择系统" style={{ width: 265 }}>
            {getFieldDecorator('index', { initialValue: currentSysName })(
              <Select placeholder="所属系统" allowClear={false} onChange={this.sysNameChange}>
                {sysNameList.map(({ index, sysName }) => (<Select.Option key={index} value={index}>{sysName}</Select.Option>))}
              </Select>
            )}
          </Form.Item>
          <Form.Item label="查询日期" style={{ width: 450 }}>
            {getFieldDecorator('timeRange', { initialValue: timeRangeInitialValue })(
              <DatePicker.RangePicker
                allowClear={false}
                format="YYYY-MM-DD HH:mm:ss"
                disabledDate={current => current > moment().add(0, 'day').endOf('day')}
                ranges={{
                  '今日': [moment().startOf('day'), moment().endOf('day')],
                  '昨日': [moment().startOf('day').subtract(1, 'day'), moment().endOf('day').subtract(1, 'day')],
                  '最近7日': [moment().startOf('day').subtract(6, 'day'), moment().endOf('day')],
                  '最近30日': [moment().startOf('day').subtract(29, 'day'), moment().endOf('day')],
                }}
                showTime={{ hideDisabledOptions: true, defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')] }}
                onOk={this.timeRangeChange}
              />
            )}
          </Form.Item>
          <Form.Item className={styles.formItemButton}>
            <Button type="primary" htmlType="submit" disabled={pageLoading || queryHistogramLoading || false}>查询</Button>
            <span className={styles.spanWidth16} />
            <Link to="/analytics/summary/data/diff">监控数据对比</Link>
          </Form.Item>
        </Row>
      </Form>
    );
  }

  // 汇总数据 - 单个卡片
  getTotalCard = (title, describe, value, loading) => {
    return (
      <Card loading={loading || false} bodyStyle={{ padding: '10px 12px 4px 12px' }} className={styles.totalCard}>
        <div className={styles.totalData}>
          <div className={styles.metaWrap}>
            <span className={styles.meta}>
              <span>{title}</span>
              <span className={styles.action}>
                <AntdTooltip title={describe}><Icon type="info-circle-o" /></AntdTooltip>
              </span>
            </span>
            <div className={styles.total}>{value}</div>
          </div>
        </div>
      </Card>
    );
  }

  // 汇总数据
  getTotal() {
    const { SummaryModel: { data: { totalData = {} } } } = this.props;
    if (!totalData) return;
    const { requestCount = 0, esCount = 0, rdsCount = 0, jdbcExecuteCount = 0, concurrentMax = 0, esResTotal = 0, rdsResTotal = 0 } = totalData;
    return (
      <div style={{ textAlign: 'center' }}>
        {this.getTotalCard('请求数', '指标说明', fmtThousands(requestCount.value))}
        <span className={styles.spanWidth16} />
        {this.getTotalCard('ES查询数', '指标说明', fmtThousands(esCount.value))}
        <span className={styles.spanWidth16} />
        {this.getTotalCard('Redis查询数', '指标说明', fmtThousands(rdsCount.value))}
        <span className={styles.spanWidth16} />
        {this.getTotalCard('JDBC执行数', '指标说明', fmtThousands(jdbcExecuteCount.value))}
        <span className={styles.spanWidth16} />
        {this.getTotalCard('最高并发', '指标说明', fmtThousands(concurrentMax.value))}
        <span className={styles.spanWidth16} />
        {this.getTotalCard('ES输出', '指标说明', fmtBytes(esResTotal.value * 8.0))}
        <span className={styles.spanWidth16} />
        {this.getTotalCard('Redis输出', '指标说明', fmtBytes(rdsResTotal.value * 8.0))}
      </div>
    );
  }

  // 直方图
  getHistogram() {
    const { queryHistogramLoading, SummaryModel: { data: { histogram = { titles: [] } }, queryParam: { histogramPrefix } } } = this.props;
    if (!histogram) return;
    const data = [];
    if (histogram && histogram.titles) {
      lodash.each(histogram.titles, (title, index) => {
        data.push({ x: title, y: histogram.histogramData[index] });
      });
    }
    const scale = {
      x: { type: 'cat', alias: histogram.xaxisTitle },
      y: { type: 'pow', alias: histogram.yaxisTitle },
    };
    if (this.chart) this.chart.forceFit();
    return (
      <Spin delay={100} spinning={queryHistogramLoading || false}>
        <Row gutter={{ md: 8, lg: 16, xl: 16 }}>
          <Col offset={1} span={3} style={{ height: 300, textAlign: 'right' }}>
            <div style={{ display: 'inline-block', textAlign: 'left', width: 120, paddingTop: 28 }}>
              {SummaryHistogramArray.map(item => {
                const selected = histogramPrefix === item.value;
                return (
                  <div
                    key={item.value}
                    style={{ marginTop: 6, cursor: selected ? undefined : 'pointer', color: selected ? '#1890ff' : 'rgba(0, 0, 0, 0.6)' }}
                    onClick={selected ? undefined : () => this.histogramPrefixChange(item.value)}
                  >
                    <Badge key={item.value} status={selected ? 'processing' : 'default'} />
                    {item.label}
                  </div>
                );
              })}
            </div>
          </Col>
          <Col span={16}>
            <Chart
              forceFit={true}
              onGetG2Instance={chart => { this.chart = chart }}
              height={300}
              width={1000}
              padding={['auto', 60, 'auto', 'auto']}
              data={data}
              scale={scale}
            >
              <Axis name="x" title={{ position: "end" }} />
              <Axis name="y" title={{ offset: 70, position: "end" }} />
              <Tooltip crosshairs={{ type: "rect" }} showTitle={false} />
              <Geom type="interval" position="x*y" tooltip="x*y">
                <Label content="y" />
              </Geom>
            </Chart>
          </Col>
        </Row>
      </Spin>
    );
  }

  // 数据表格
  getTable() {
    let { screenHeight } = this.state;
    screenHeight -= 802;
    if (screenHeight < 260) screenHeight = 500;
    const { pageLoading, SummaryModel: { data: { tableData } } } = this.props;
    let data = [];
    if (tableData
      && tableData.aggregations
      && tableData.aggregations['group_by@@timestamp@@timestamp']
      && tableData.aggregations['group_by@@timestamp@@timestamp'].buckets) {
      data = tableData.aggregations['group_by@@timestamp@@timestamp'].buckets;
    }
    const columns = [
      { title: '时间', dataIndex: 'key_as_string', width: 135 },
      { title: '请求数', dataIndex: 'sum@@timestamp@requestCount.value', width: 70, render: text => fmtThousands(text) },
      { title: '最高并发', dataIndex: 'max@@timestamp@concurrentMax.value', width: 80, render: text => fmtThousands(text) },
      { title: 'Redis执行', dataIndex: 'sum@@timestamp@rdsCount.value', width: 90, render: text => fmtThousands(text) },
      { title: 'Redis总耗时', dataIndex: 'sum@@timestamp@rdsCostTotal.value', width: 100, render: text => fmtTime(text, 2) },
      { title: 'Redis最大耗时', dataIndex: 'max@@timestamp@rdsCostMax.value', width: 120, render: text => fmtTime(text, 2) },
      { title: 'Redis总输出', dataIndex: 'sum@@timestamp@rdsResTotal.value', width: 120, render: text => fmtBytes(text) },
      { title: 'ES执行', dataIndex: 'sum@@timestamp@esCount.value', width: 80, render: text => fmtThousands(text) },
      { title: 'ES总耗时', dataIndex: 'sum@@timestamp@esCostTotal.value', width: 90, render: text => fmtTime(text, 2) },
      { title: 'ES最大耗时', dataIndex: 'max@@timestamp@esCostMax.value', width: 100, render: text => fmtTime(text, 2) },
      { title: 'ES总输出', dataIndex: 'sum@@timestamp@esResTotal.value', width: 90, render: text => fmtBytes(text) },
      { title: 'JDBC高峰', dataIndex: 'max@@timestamp@jdbcActivePeak.value', width: 90, render: text => fmtThousands(text) },
      { title: '连接池高峰', dataIndex: 'max@@timestamp@jdbcPoolingPeak.value', width: 100, render: text => fmtThousands(text) },
      { title: 'JDBC执行数', dataIndex: 'sum@@timestamp@jdbcExecuteCount.value', width: 100, render: text => fmtThousands(text) },
      { title: 'JDBC异常数', dataIndex: 'sum@@timestamp@jdbcErrorCount.value', width: 100, render: text => fmtThousands(text) },
      { title: '开始事务', dataIndex: 'sum@@timestamp@startTransactionCount.value', width: 80, render: text => fmtThousands(text) },
      { title: '提交事务', dataIndex: 'sum@@timestamp@jdbcCommitCount.value', width: 80, render: text => fmtThousands(text) },
      { title: '回滚次数', dataIndex: 'sum@@timestamp@jdbcRollbackCount.value', width: 80, render: text => fmtThousands(text) },
      { title: '执行总耗时', dataIndex: 'sum@@timestamp@jdbcExecuteTimeMillis.value', width: 90, render: text => fmtTime(text, 2) },
      { title: '查询总行数', dataIndex: 'sum@@timestamp@jdbcFetchRowCount.value', width: 90, render: text => fmtThousands(text) },
      { title: '更新总行数', dataIndex: 'sum@@timestamp@jdbcUpdateCount.value', width: 90, render: text => fmtThousands(text) },
      { title: '非空等待总时长', dataIndex: 'sum@@timestamp@notEmptyWaitMillis.value', width: 120, render: text => fmtTime(text, 2) },
      { title: '机器人访问次数', dataIndex: 'sum@@timestamp@botCount.value', width: 120, render: text => fmtThousands(text) },
    ];

    return (
      <Table
        size="middle"
        bordered={true}
        rowKey={record => record.key}
        columns={columns}
        loading={pageLoading}
        dataSource={data}
        scroll={{ x: 2200, y: screenHeight }}
        pagination={{
          pageSize: 50,
          hideOnSinglePage: false,
          pageSizeOptions: ['30', '50', '100'],
          showSizeChanger: true, showQuickJumper: true,
          showTotal: total => `总记录数${total}条`,
        }}
      />
    );
  }

  render() {
    const { pageLoading } = this.props;
    return (
      <PageHeaderLayout>
        <Card bordered={false}>
          <Fragment>
            <div className={styles.queryForm}>
              {this.queryForm()}
            </div>
            <Spin delay={100} size="large" spinning={pageLoading} tip="加载数据...">
              {this.getTotal()}
              {this.getHistogram()}
              {this.getTable()}
            </Spin>
          </Fragment>
        </Card>
      </PageHeaderLayout>
    );
  }
}
